﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace PLCNodeInterfaceBase
{

    public enum PLCNodeProtocolType
    {
        Modbus = 1,
        COAP,
    }

    /// <summary>
    /// PLC节点对象数据提取接口，用于节点向外部程序提供数据使用
    /// </summary>
    public interface PLCNodeInterface
    {
        /// <summary>
        /// 节点协议类型
        /// </summary>
        PLCNodeProtocolType PLCProtocolType { get; }
        /// <summary>
        /// PLC是否正常连接，通过判断PLCDisconnectCount获得，可重载
        /// </summary>
        bool IsConnted { get; }
        /// <summary>
        /// PLC丢失连接计数
        /// </summary>
        int PLCDisconnectCount { get; }
        /// <summary>
        /// PLC的地址（Modbus）
        /// </summary>
        int PLCAddress0 { get; }
        /// <summary>
        /// PLC网络地址
        /// </summary>
        IPEndPoint PLCIPEndPoint { get; }
        /// <summary>
        /// PLC寄存器数量
        /// </summary>
        int PLCRegCount { get;  }
        /// <summary>
        /// PLC寄存器起始地址
        /// </summary>
        int PLCRegAddrStar { get; }
        /// <summary>
        /// PLC当前映射的所有寄存器值
        /// </summary>
        ushort[] RegValues { get; }
        /// <summary>
        /// PLC寄存器映射中是否有新的数据
        /// 该值读取后变为false；
        /// </summary>
        bool HasNewData { get; }
        /// <summary>
        /// 读取PLC寄存器值到映射中的周期，单位：ms
        /// </summary>
        int IntervalOfFlash { get; set; }
        /// <summary>
        /// 读取寄存器，地址为绝对地址，从0开始
        /// </summary>
        /// <param name="fAbsRegAddress">寄存器绝对地址，从0开始</param>
        /// <param name="fRegValue">读取的结果</param>
        /// <returns>地址正确，返回true，否则返回false</returns>
        bool ReadRegValueAbsAddr(int fAbsRegAddress, out ushort fRegValue);
        /// <summary>
        /// 修改寄存器，该函数可同时修改多个个寄存器，可重载
        /// 原理：
        /// 利用事件ModbusNodeWriteRegBack OnWriteRegBacke，将生成的命令发送；
        /// </summary>
        /// <param name="fRegStar">要修改的寄存器起始值，绝对地址，从0开始</param>
        /// <param name="fRegValues">要写入的寄存器值</param>
        /// <returns>成功发送数据，返回true</returns>
        bool WriteRegValue(ushort fRegStar, ushort[] fRegValues);
        /// <summary>
        /// 修改寄存器，该函数只能修改1个寄存器，可重载
        /// 原理：
        /// 将需要发送的命令放入中间属性TModbusRTUCommandV2 WriteRegCommand，
        /// 由上级总线自动判断该函数是否为空，不为空则发送数据
        /// </summary>
        /// <param name="fRegAddress"></param>
        /// <param name="fRegValue"></param>
        /// <returns></returns>
        bool WriteRegValue(int fRegAddress, ushort fRegValue);

        bool SendMBCommand(object MBCommand);
        /// <summary>
        /// 清场关闭对象，可重载
        /// </summary>
        void CloseAll();
        /// <summary>
        /// PLC序列号
        /// </summary>
        string PLCSNStr { get; }
        /// <summary>
        /// PLC序列号，反序
        /// </summary>
        byte[] PLCSNByteLF { get; }
    }
    
}
